# -*- coding:utf-8 -*-
"""Created By Corvo"""

from mod.common.minecraftEnum import EntityType

from ....server.system.base import *


# 区域接口
class AreaInterface(object):
    """区域接口"""

    def Online(self):
        pass

    def Offline(self):
        pass

    def OnUpdateSecond(self):
        """
        秒更新\n
        - 管理调用
        """

    def OnMobDie(self, entity_id):
        # type: (str) -> None
        """
        生物死亡触发\n
        - 由管理调用
        """

    def OnMobRemove(self, entity_id):
        # type: (str) -> None
        """
        生物移除触发\n
        - 由管理调用
        """


# 区域基类
class AreaBase(ServerBaseSystem, AreaInterface):
    """区域基类"""
    __mVersion__ = 2

    def __init__(self, position, dimension):
        self.position = position
        self.dim = dimension
        self.chunk_pos_x = position[0] // 16
        self.chunk_pos_z = position[2] // 16
        super(AreaBase, self).__init__(MDKConfig.GetModuleServer())
        
        level_id = serverApi.GetLevelId()
        self.dim_comp = self.comp_factory.CreateDimension(level_id)
        self.chunk_comp = self.comp_factory.CreateChunkSource(level_id)

    def ConfigEvent(self):
        super(AreaBase, self).ConfigEvent()
        self.defaultEvent.update({
            ServerEvent.ChunkLoadedServerEvent: self.ChunkLoadedServerEvent,
            ServerEvent.ChunkAcquireDiscardedServerEvent: self.ChunkAcquireDiscardedServerEvent,
        })

    # -----------------------------------------------------------------------------------

    """api"""

    # 尝试激活区域
    def Active(self):
        """尝试激活区域"""

        def active():
            for _ in xrange(15):
                yield 30
                if self.chunk_comp.CheckChunkState(self.dim, self.position):
                    self.Online()
                    return
            print "[warn]", "启动失败"

        self.StartCoroutine(active)

    # -----------------------------------------------------------------------------------

    def ChunkLoadedServerEvent(self, args):
        if args["dimension"] != self.dim:
            return
        if args["chunkPosX"] == self.chunk_pos_x and args["chunkPosZ"] == self.chunk_pos_z:
            self.Online()

    def ChunkAcquireDiscardedServerEvent(self, args):
        if args["dimension"] != self.dim:
            return
        if args["chunkPosX"] == self.chunk_pos_x and args["chunkPosZ"] == self.chunk_pos_z:
            self.Offline()


# 触发区域基类
class TriggerArea(AreaBase):
    """触发区域基类"""
    __mVersion__ = 3

    def __init__(self, position, dimension, aabb):
        self.aabb = aabb
        self.area_id = self.__class__.__name__ + str(aabb)
        self.start_pos = self.aabb[:3]
        self.end_pos = self.aabb[3:]

        # 是否启动区域
        self.is_active_area = False

        self._ban_list = self.ConfigBanEntityList()
        self._interest_type = self.ConfigInterestEntityType()
        super(TriggerArea, self).__init__(position, dimension)

    def OnDestroy(self):
        self.Offline()
        super(TriggerArea, self).OnDestroy()

    # -----------------------------------------------------------------------------------

    """配置相关"""

    # 配置禁止生物列表
    def ConfigBanEntityList(self):
        # type: () -> list
        """配置禁止生物列表"""
        return []

    # 配置感兴趣生物列表
    def ConfigInterestEntityType(self):
        # type: () -> int
        """配置感兴趣生物类型"""
        return EntityType.Player

    """触发相关"""

    # 进入区域生物
    def OnEntityInArea(self, entities):
        """进入区域生物"""

    # 离开区域生物
    def OnEntityLeaveArea(self, entities):
        """离开区域生物"""

    # -----------------------------------------------------------------------------------

    """接口相关"""

    # 获取感应区域生物
    def GetAreaEntity(self):
        # type: () -> list
        """获取感应区域生物"""
        return self.game_comp.GetEntitiesInSquareArea(None, self.start_pos, self.end_pos, self.dim)

    # 注册感应区域
    def RegisterArea(self):
        # type: () -> bool
        """注册感应区域"""
        if self.is_active_area:
            return True
        if self.dim_comp.RegisterEntityAOIEvent(self.dim, self.area_id, self.aabb, self._ban_list, self._interest_type):
            # print "[suc]", "启动感应区域：", self.area_id
            self.is_active_area = True
            return True
        return False

    # 召唤生物
    def SpawnEntity(self, engine_type, pos, rot=(0, 0)):
        # type: (str, tuple, tuple) -> str
        """召唤生物"""
        return self.AddEntity(engine_type, pos, self.dim, rot)

    # -----------------------------------------------------------------------------------

    def Online(self):
        self.ListenDefaultEvent(ServerEvent.NewOnEntityAreaEvent, self.NewOnEntityAreaEvent)

        def active():
            for _ in xrange(15):
                yield 30
                if self.RegisterArea():
                    return

        self.StartCoroutine(active)

    def Offline(self):
        self.UnListenDefaultEvent(ServerEvent.NewOnEntityAreaEvent, self.NewOnEntityAreaEvent)
        enable = self.dim_comp.UnRegisterEntityAOIEvent(self.dim, self.area_id)
        self.is_active_area = not enable

    # -----------------------------------------------------------------------------------

    def NewOnEntityAreaEvent(self, args):
        if args["name"] == self.area_id:
            if args["enteredEntities"]:
                self.OnEntityInArea(args["enteredEntities"])
            elif args["leftEntities"]:
                self.OnEntityLeaveArea(args["leftEntities"])
